home *** CD-ROM | disk | FTP | other *** search
/ The 640 MEG Shareware Studio 2 / The 640 Meg Shareware Studio CD-ROM Volume II (Data Express)(1993).ISO / clang / nn.zip / EXPIRE.C < prev    next >
C/C++ Source or Header  |  1989-12-29  |  4KB  |  198 lines

  1. /*
  2.  *    Expire will remove all entries in the index and data files
  3.  *    corresponding to the articles before the first article registered
  4.  *    in the active file.  No attempt is made to eliminate other
  5.  *    expired articles.
  6.  */
  7.  
  8. #include "config.h"
  9. #include "db.h"
  10.  
  11. import int trace;
  12.  
  13. #define expire_error(msg) { \
  14.     err_message = msg; \
  15.     goto error_handler; \
  16. }
  17.  
  18. long expire_group(gh)
  19. register group_header *gh;
  20. {
  21.     FILE *old_x, *old_d;
  22.     FILE        *new;
  23.     off_t        index_offset, data_offset, new_offset;
  24.     long        count, expire_count;
  25.     char         *err_message;
  26.  
  27.     old_x = old_d = new = NULL;
  28.     
  29.  
  30.     if (trace)
  31.     log_entry('T', "Exp %s (%d -> %d)",
  32.           gh->group_name, gh->first_l_article, gh->first_article);
  33.     
  34.     /*
  35.      * check whether new first article is collected
  36.      */
  37.  
  38.     if (!art_collected(gh, gh->first_article)) {
  39.     expire_count = gh->first_l_article - gh->last_l_article + 1;
  40.     err_message = NULL;
  41.     goto error_handler;    /* renumbering, collect from start */
  42.     }
  43.     
  44.     expire_count = gh->first_article - gh->first_l_article;
  45.  
  46.     new = NULL;
  47.  
  48.     /*
  49.      *  Open old files, unlink after open
  50.      */
  51.  
  52.     old_x = open_data_file(gh, 'x', OPEN_READ|OPEN_UNLINK);
  53.     old_d = open_data_file(gh, 'd', OPEN_READ|OPEN_UNLINK);
  54.  
  55.     if (old_x == NULL || old_d == NULL)
  56.     expire_error("INDEX or DATA file missing");
  57.     
  58.     /*
  59.      *    Create new index file; copy from old
  60.      */
  61.  
  62.     new = open_data_file(gh, 'x', OPEN_CREATE);
  63.     if (new == NULL)
  64.     expire_error("INDEX: cannot create");
  65.  
  66.     /*
  67.      *    index_offset is the offset into the old index file for the
  68.      *    first entry in the new index file
  69.      */
  70.  
  71.     index_offset = get_index_offset(gh, gh->first_article);
  72.  
  73.     /*
  74.      *    adjust the group's index write offset (the next free entry)
  75.      */
  76.  
  77.     gh->index_write_offset -= index_offset;
  78.  
  79.     /*
  80.      *    calculate the number of entries to copy
  81.      */
  82.  
  83.     count = gh->index_write_offset / sizeof(off_t);
  84.  
  85.     /*
  86.      *    data offset is the offset into the old data file for the
  87.      *    first byte in the new data file; it is initialized in the
  88.      *    loop below, by reading the entry in the old index file at
  89.      *    offset 'index_offset'.
  90.      */
  91.  
  92.     data_offset = (off_t)0;
  93.  
  94.     /*
  95.      *    read 'count' entries from the old index file starting from
  96.      *    index_offset, subtract the 'data_offset', and output the
  97.      *    new offset to the new index file.
  98.      */
  99.  
  100.     fseek(old_x, index_offset, 0);
  101.     
  102.     while (--count >= 0) {
  103.     if (!db_read_offset(old_x, &new_offset))
  104.         expire_error("INDEX: too short");
  105.  
  106.     if (data_offset == (off_t)0) data_offset = new_offset;
  107.  
  108.     new_offset -= data_offset;
  109.     if (!db_write_offset(new, &new_offset))
  110.         expire_error("NEW INDEX: cannot write");
  111.     }
  112.  
  113.     fclose(new);
  114.     fclose(old_x); old_x = NULL;
  115.     
  116.     /*
  117.      *    copy from old data file to new data file
  118.      */
  119.  
  120.     new = open_data_file(gh, 'd', OPEN_CREATE);
  121.     if (new == NULL)
  122.     expire_error("DATA: cannot create");
  123.     
  124.     /*
  125.      *    calculate offset for next free entry in the new data file
  126.      */
  127.  
  128.     gh->data_write_offset -= data_offset;
  129.  
  130.     /*
  131.      *    calculate number of bytes to copy (piece of cake)
  132.      */
  133.  
  134.     count = gh->data_write_offset;
  135.     
  136.     /*
  137.      *    copy 'count' bytes from the old data file, starting at offset
  138.      *     'data_offset', to the new data file
  139.      */
  140.  
  141.     fseek(old_d, data_offset, 0);
  142.     while (count > 0) {
  143.     char block[1024];
  144.     int  count1;
  145.     
  146.     count1 = fread(block, sizeof(char), 1024, old_d);
  147.     if (count1 <= 0)
  148.         expire_error("DATA: read error");
  149.  
  150.     if (fwrite(block, sizeof(char), count1, new) != count1)
  151.         expire_error("DATA: write error");
  152.     
  153.     count -= count1;
  154.     }
  155.     
  156.     fclose(new);
  157.     fclose(old_d);
  158.     
  159.     /*
  160.      *    Update group entry
  161.      */
  162.  
  163.     gh->first_l_article = gh->first_article;
  164.  
  165.     /*
  166.      *    Return number of expired articles
  167.      */
  168.  
  169.     return expire_count;
  170.     
  171.  
  172.  
  173.     /*
  174.      *    Errors end up here.
  175.      *    We simply recollect the whole group once more.
  176.      */
  177.  
  178. error_handler:
  179.  
  180.     if (new) fclose(new);
  181.     if (old_x) fclose(old_x);
  182.     if (old_d) fclose(old_d);
  183.     
  184.     if (err_message)
  185.     log_entry('E', "Expire Error (%s): %s", gh->group_name, err_message);
  186.  
  187.     clean_group(gh);
  188.  
  189.     /* will be saved & unblocked later */
  190.  
  191.     /*
  192.      *    We cannot say whether any articles actually had to be expired,
  193.      *    but then we must guess...
  194.      */
  195.  
  196.     return expire_count;
  197. }
  198.